package data.dialect;

import java.sql.Statement;
import java.util.Properties;
import org.apache.ibatis.executor.resultset.FastResultSetHandler;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.plugin.Signature;

															
@Intercepts({@Signature(type=ResultSetHandler.class,
		method="handleResultSets",args={Statement.class})})
public class DialectResultHandlerInterceptor implements Interceptor {
	public Object intercept(Invocation arg0) throws Throwable {
		FastResultSetHandler rsHandler = (FastResultSetHandler)arg0.getTarget();
        RowBounds rowBounds = (RowBounds)ReflectUtil.getFieldValue(
				rsHandler, "rowBounds");	       
        if (rowBounds.getLimit() > 0
                && rowBounds.getLimit() < RowBounds.NO_ROW_LIMIT)
        {
        	int offset = 0;
        	int limit = RowBounds.NO_ROW_LIMIT;
        	String dialectStr = getDialectString(rsHandler);
        	if ("SQLSERVER".equals(dialectStr)){
        		offset = rowBounds.getOffset()-1;
        		if (offset < 0){
        			offset = 0;
        		}
        	}
        	else if ("SYBASE".equals(dialectStr) || dialectStr==null){
        		offset = rowBounds.getOffset()-1;
        		if (offset < 0){
        			offset = 0;
        		}
        		limit = rowBounds.getLimit();
        	}
            ReflectUtil.setFieldValue(rsHandler, "rowBounds", 
            	new RowBounds(offset, limit));
        }
        return arg0.proceed();
	}

	private String getDialectString(FastResultSetHandler rsHandler){
        Configuration configuration = (Configuration)ReflectUtil.getFieldValue(
        		rsHandler, "configuration");
        String str = configuration.getVariables().getProperty("dialect");
        if (str != null){
        	str = str.toUpperCase();
        }
        return str;
	}

	public Object plugin(Object arg0) {
		return Plugin.wrap(arg0, this);
	}

	public void setProperties(Properties arg0) {
	}
}
